import 'package:flutter/material.dart';
import '../system/fontsize_provider.dart';
import 'package:provider/provider.dart';
import 'package:http/http.dart' as http;
import '../../services/api_service.dart';
import 'dart:convert';
import '../../services/auth_service.dart';
import '../../utils/message_box.dart';

class SinglePickingScreen extends StatefulWidget {
  const SinglePickingScreen({super.key});

  @override
  _SinglePickingScreenState createState() => _SinglePickingScreenState();
}

class _SinglePickingScreenState extends State<SinglePickingScreen> {
  int? warehouseId;
  int? waveId; 
  late List<String> orders = []; 
  late List<Map<String, dynamic>> waveList = []; 
  final TextEditingController _manualWarehouseController = TextEditingController();

  String? selectedWave; 
  String? waveName;
  String? waveStatus;
  final TextEditingController binController = TextEditingController();
  final FocusNode binFocusNode = FocusNode();
  String combinedValue = '';
  late double _fontScale;

  @override
  void initState() {
    super.initState();
    _getWarehouseId().then((_) {
      if (warehouseId != null) {
        getWaveList();
      } else {
        MessageBox.showMessageBox(context, 'Invaild token, please refresh current page.', isError: true);
      }
    });
    WidgetsBinding.instance.addPostFrameCallback((_) {
      // FocusScope.of(context).requestFocus(binFocusNode);
    });
  }

  @override
  void dispose() {
    binController.dispose();
    binFocusNode.dispose();
    _manualWarehouseController.dispose();
    super.dispose();
  }

  Future<void> _getWarehouseId() async {
    final user = Provider.of<AuthService>(context, listen: false).currentUser;
    if (user?.warehouse != null) {
      setState(() {
        warehouseId = user?.warehouse;
      });
    }
  }

  void updateCombinedValue() {
    setState(() {
      combinedValue = selectedWave != null && binController.text.isNotEmpty
          ? '$selectedWave | ${binController.text}'
          : '';
    });
  }

  Future<void> getWaveList() async {
    if (warehouseId == null) {
      MessageBox.showMessageBox(context, 'Invaild token, please refresh current page.', isError: true);
      return;
    }

    final apiUrl = '${ApiService.baseURL}${ApiService.getWaveList}';
    final authService = Provider.of<AuthService>(context, listen: false);
    final accessToken = authService.accessToken;

    if (accessToken == null || accessToken.isEmpty) {
      MessageBox.showMessageBox(context, 'Authentication failed', isError: true);
      return;
    }

    try {
      print('getWaveList url--$apiUrl');
      print('Using warehouseId: $warehouseId');

      final response = await http.get(
        Uri.parse(apiUrl),
        headers: {
          'Authorization': 'JWT $accessToken',
          'x-warehouse-id': '$warehouseId',
          'x-timezone': 'America/Los_Angeles',
          'Content-Type': 'application/json',
          'X-Client-Type': 'app'
        },
      );

      if (response.statusCode == 200) {
        final jsonData = json.decode(utf8.decode(response.bodyBytes)) as Map<String, dynamic>;
        print('getWaveList jsonData--$jsonData');
        if (jsonData['code'] == 2000) {
          waveList = (jsonData['data'] as List<dynamic>).cast<Map<String, dynamic>>();
          setState(() {
            orders = waveList
                .map((wave) => '${wave['name']} | ${wave['status']}')
                .toSet()
                .toList();
          });

          if (orders.isEmpty) {
            MessageBox.showMessageBox(context, 'No wave data found.');
          }
        } else {
          MessageBox.showMessageBox(context, jsonData['msg'], isError: true);
        }
      } else if (response.statusCode == 401) {
        AuthService().logout(context);
        MessageBox.showMessageBox(context, 'Session expired, please log in again.', isError: true);
      } else {
        MessageBox.showMessageBox(context, 'Server error: ${response.statusCode}', isError: true);
      }
    } catch (e) {
      MessageBox.showMessageBox(context, e.toString(), isError: true);
    }
  }

  Future<Map<String, dynamic>?> startPicking() async {
    if (warehouseId == null) {
      throw('Invaild token, please refresh current page.');
    }
    if (waveId == null) {
      throw('Please select one wave firstly.');
    }

    final apiUrl = '${ApiService.baseURL}${ApiService.startPicking}';
    final authService = Provider.of<AuthService>(context, listen: false);
    final accessToken = authService.accessToken;

    if (accessToken == null || accessToken.isEmpty) {
      throw('Authentication failed');
    }

    try {
      print('startPicking url--$apiUrl');
      print('Using warehouseId: $warehouseId, waveId: $waveId');
      final requestBody = {
        'pickwave': waveId
    };
      final response = await http.post(
        Uri.parse(apiUrl),
        headers: {
          'Authorization': 'JWT $accessToken',
          'x-warehouse-id': '$warehouseId',
          'x-timezone': 'America/Los_Angeles',
          'Content-Type': 'application/json',
          'X-Client-Type': 'app'
        },
        body: jsonEncode(requestBody),
      );

      if (response.statusCode == 200) {
        final jsonData = json.decode(utf8.decode(response.bodyBytes)) as Map<String, dynamic>;
        print('jsonData--$jsonData');
        return jsonData.isNotEmpty ? jsonData : null;
      } else if (response.statusCode == 401) {
        AuthService().logout(context);
        throw('Session expired, please log in again.');
      } else {
        throw('Server error: ${response.statusCode}');
      }
    } catch (e) {
      throw(e.toString());
    }
  }

  Future<void> _handleStartPicking() async {
    try{
      if(waveStatus != null && waveStatus == 'Completed'){
        throw('The wave already picked.');
      }
      final pickTaskData = await startPicking();
      if(pickTaskData != null && pickTaskData['code'] == 2000){
        Navigator.pushNamed(
            context,
            '/picking/picking',
            arguments: {
              'waveId': waveId,
              'source': 'singlePicking'
            },
          ).then((result) {
          if (result == true) {
            getWaveList();
            setState(() {
              selectedWave = null;
              waveName = null;
              waveStatus = null;
              binController.clear();
              combinedValue = '';
            });
          }
        });
      }
      else{
        throw('${pickTaskData!['msg']}');
      }
    }catch(e){
      MessageBox.showMessageBox(context, e, isError: true);
    }
  }

  @override
  Widget build(BuildContext context) {
    _fontScale = Provider.of<FontSizeProvider>(context).fontScale;
    final bool isOkEnabled = selectedWave != null && binController.text.isNotEmpty;

    return Scaffold(
      appBar: AppBar(
        title: Text('Single Picking', style: TextStyle(fontSize: 18 * _fontScale)),
        leading: IconButton(
          icon: const Icon(Icons.arrow_back, color: Colors.white),
          onPressed: () => Navigator.pushNamed(context, '/outbound'),
        ),
        actions: [
          IconButton(
            icon: const Icon(Icons.home, color: Colors.white),
            onPressed: () => Navigator.pushNamed(context, '/home'),
          ),
        ],
        backgroundColor: const Color(0xFF008363),
      ),
      body: GestureDetector(
        onTap: () => FocusScope.of(context).unfocus(),
        behavior: HitTestBehavior.opaque,
        child: Column(
          children: [
            Expanded(
              child: SingleChildScrollView(
                padding: const EdgeInsets.only(left: 32,right: 32,top: 10,bottom: 64),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      'Waves:',
                      style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14 * _fontScale),
                    ),
                    const SizedBox(height: 8),
                    Container(
                      decoration: BoxDecoration(
                        border: Border.all(color: Colors.grey),
                        borderRadius: BorderRadius.circular(4),
                      ),
                      height: 150,
                      child: ListView.builder(
                        itemCount: orders.length,
                        itemBuilder: (context, index) {
                          final order = orders[index];
                          final isSelected = selectedWave == order;

                          return InkWell(
                            child: Container(
                            color: isSelected ? Colors.green[50] : null,
                            padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
                            child: Text(
                              order,
                              style: TextStyle(
                                fontSize: 13 * _fontScale,
                                color: isSelected ? Colors.green : Colors.black,
                                fontWeight: FontWeight.bold,
                              ),
                            ),
                            ),
                            onTap: () {
                              setState(() {
                                if (isSelected) {
                                  selectedWave = null;
                                  waveId = null;
                                  waveName = null;
                                } else {
                                  selectedWave = order;
                                  final matchedWave = waveList.firstWhere(
                                    (wave) => '${wave['name']} | ${wave['status']}' == order,
                                    orElse: () => {},
                                  );
                                  waveName = selectedWave!.split(' | ')[0];
                                  waveStatus = selectedWave!.split(' | ')[1];
                                  waveId = matchedWave.isNotEmpty ? matchedWave['id'] as int? : null;
                                }
                                updateCombinedValue();
                              });
                            },
                          );
                        },
                      ),
                    ),
                    const SizedBox(height: 16),
                    Text(
                      'Wave:',
                      style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14 * _fontScale),
                    ),
                    SizedBox(
                      height: 30,
                      child: TextFormField(
                        readOnly: true,
                        decoration: const InputDecoration(
                          border: OutlineInputBorder(),
                          hintText: 'Select a wave above',
                          contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 0),
                        ),
                        controller: TextEditingController(text: waveName),
                        style: TextStyle(fontSize: 13 * _fontScale),
                      ),
                    ),
                    const SizedBox(height: 16),
                    Text(
                      'LPN:',
                      style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14 * _fontScale),
                    ),
                    SizedBox(
                      height: 30,
                      child: TextFormField(
                        focusNode: binFocusNode,
                        controller: binController,
                        decoration: const InputDecoration(
                          border: OutlineInputBorder(),
                          hintText: 'Scan or enter LPN',
                          contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 0),
                        ),
                        style: TextStyle(fontSize: 13 * _fontScale),
                        onChanged: (_) => updateCombinedValue(),
                      ),
                    ),
                    const SizedBox(height: 16),
                    Text(
                      'Waves | LPN:',
                      style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14 * _fontScale),
                    ),
                    Container(
                      padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
                      width: double.infinity,
                      decoration: BoxDecoration(
                        border: Border.all(color: Colors.grey),
                        borderRadius: BorderRadius.circular(4),
                      ),
                      child: Text(
                        combinedValue,
                        style: TextStyle(
                          fontSize: 16 * _fontScale,
                          color: combinedValue.isNotEmpty ? Colors.black : Colors.grey,
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 8),
              child: Column(
                children: [
                  SizedBox(
                    width: double.infinity,
                    child: ElevatedButton(
                      onPressed: isOkEnabled ? () {} : null,
                      style: ElevatedButton.styleFrom(
                        backgroundColor: const Color(0xFF008363),
                        disabledBackgroundColor: Colors.grey,
                        padding: const EdgeInsets.symmetric(vertical: 1),
                      ),
                      child: Text('OK', style: TextStyle(color: Colors.white, fontSize: 14 * _fontScale)),
                    ),
                  ),
                  const SizedBox(height: 3),
                  SizedBox(
                    width: double.infinity,
                    child: ElevatedButton(
                      onPressed: null,
                      style: ElevatedButton.styleFrom(
                        backgroundColor: const Color(0xFF008363),
                        disabledBackgroundColor: Colors.grey,
                        padding: const EdgeInsets.symmetric(vertical: 1),
                      ),
                      child: Text('Rollback', style: TextStyle(color: Colors.white, fontSize: 14 * _fontScale)),
                    ),
                  ),
                  const SizedBox(height: 3),
                  SizedBox(
                    width: double.infinity,
                    child: ElevatedButton.icon(
                      onPressed: waveName != null ? _handleStartPicking : null,
                      style: ElevatedButton.styleFrom(
                        backgroundColor: const Color(0xFF008363),
                        disabledBackgroundColor: Colors.grey,
                        padding: const EdgeInsets.symmetric(vertical: 1),
                      ),
                      label: Text(
                        'Start Picking',
                        style: TextStyle(color: Colors.white, fontSize: 14 * _fontScale),
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}